#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
#include <getopt.h>
#include "../common/clog.h"
#include "../common/config.h"
#include "../common/common.h"

typedef struct {
    char process_filter[MAX_PROCESS_NAME_LEN];
    clog_level_t level_filter;
    int show_all_processes;
    int show_all_levels;
} filter_t;

// 函数声明
void print_usage(const char* program_name);
int should_display_log(const log_message_t* msg, const filter_t* filter);
void print_log_message(const log_message_t* msg);
void* log_reader(void* arg);

void print_usage(const char* program_name) {
    printf("Usage: %s [options]\n", program_name);
    printf("Options:\n");
    printf("  -p <process_name>  Filter by process name\n");
    printf("  -l <level>         Filter by log level (info|debug|warning|error)\n");
    printf("  -h                 Show help\n");
    printf("Examples:\n");
    printf("  %s                 Show all logs\n", program_name);
    printf("  %s -p test_app     Show logs from test_app process\n", program_name);
    printf("  %s -l error        Show only error logs\n", program_name);
    printf("  %s -p test_app -l warning  Show warning logs from test_app\n", program_name);
}

int should_display_log(const log_message_t* msg, const filter_t* filter) {
    // 检查进程名过滤
    if (!filter->show_all_processes) {
        if (strcmp(msg->process_name, filter->process_filter) != 0) {
            return 0;
        }
    }
    
    // 检查日志级别过滤
    if (!filter->show_all_levels) {
        if (msg->level != filter->level_filter) {
            return 0;
        }
    }
    
    return 1;
}

void print_log_message(const log_message_t* msg) {
    print_log_to_console(msg, 1); // 启用颜色输出
}

void* log_reader(void* arg) {
    filter_t* filter = (filter_t*)arg;
    log_config_t config;
    load_log_config("log_config.conf", &config);
    
    printf("Log viewer started with filters:\n");
    if (!filter->show_all_processes) {
        printf("  Process: %s\n", filter->process_filter);
    } else {
        printf("  Process: ALL\n");
    }
    if (!filter->show_all_levels) {
        printf("  Level: %s\n", get_level_string(filter->level_filter));
    } else {
        printf("  Level: ALL\n");
    }
    printf("Press Ctrl+C to exit\n\n");
    
    // 检查日志目录是否存在
    struct stat st;
    if (stat(config.log_path, &st) != 0 || !S_ISDIR(st.st_mode)) {
        printf("Log directory does not exist: %s\n", config.log_path);
        printf("Please start the log server first to create log files.\n");
        return NULL;
    }
    
    // 首先显示现有日志内容
    char command[1024];
    if (!filter->show_all_processes) {
        snprintf(command, sizeof(command), "find %s -name '%s.log' -type f", 
                 config.log_path, filter->process_filter);
    } else {
        snprintf(command, sizeof(command), "find %s -name '*.log' -type f", 
                 config.log_path);
    }
    
    // 检查是否有日志文件
    FILE* check_pipe = popen(command, "r");
    if (!check_pipe) {
        perror("Failed to check log files");
        return NULL;
    }
    
    char file_path[1024];
    int has_files = 0;
    
    printf("Displaying existing logs:\n");
    printf("========================\n");
    
    // 显示现有日志文件内容
    while (fgets(file_path, sizeof(file_path), check_pipe)) {
        has_files = 1;
        // 去除换行符
        file_path[strcspn(file_path, "\n")] = 0;
        
        FILE* log_file = fopen(file_path, "r");
        if (log_file) {
            char line[1024];
            while (fgets(line, sizeof(line), log_file)) {
                // 解析和显示日志行
                char timestamp[32], level_str[16], process_name[64], message[512];
                if (sscanf(line, "[%31[^]]] [%15[^]]] [%63[^]]] %511[^\n]",
                           timestamp, level_str, process_name, message) == 4) {
                    
                    // 转换级别字符串为枚举
                    clog_level_t level = (clog_level_t)-1;
                    if (strcmp(level_str, "I") == 0) level = CLOG_INFO;
                    else if (strcmp(level_str, "D") == 0) level = CLOG_DEBUG;
                    else if (strcmp(level_str, "W") == 0) level = CLOG_WARNING;
                    else if (strcmp(level_str, "E") == 0) level = CLOG_ERROR;
                    
                    if (level != (clog_level_t)-1) {
                        log_message_t msg;
                        msg.level = level;
                        strcpy(msg.process_name, process_name);
                        strcpy(msg.timestamp, timestamp);
                        strcpy(msg.message, message);
                        
                        if (should_display_log(&msg, filter)) {
                            print_log_message(&msg);
                        }
                    }
                }
            }
            fclose(log_file);
        }
    }
    pclose(check_pipe);
    
    if (!has_files) {
        printf("No log files found in %s\n", config.log_path);
        printf("Please start some applications that use the log system.\n");
        printf("\n========================\n");
        printf("Waiting for log files to be created...\n");
        printf("========================\n");
        // 不要立即退出，而是继续监控
    } else {
        printf("\n========================\n");
        printf("Monitoring for new logs...\n");
        printf("========================\n");
    }
    
    // 现在开始监控新的日志
    if (!filter->show_all_processes) {
        snprintf(command, sizeof(command), "tail -f %s/%s.log 2>/dev/null",
                 config.log_path, filter->process_filter);
    } else {
        snprintf(command, sizeof(command), "tail -f %s/*.log 2>/dev/null",
                 config.log_path);
    }
    
    FILE* pipe = popen(command, "r");
    if (!pipe) {
        perror("popen failed");
        return NULL;
    }
    
    char line[1024];
    while (fgets(line, sizeof(line), pipe)) {
        // 解析日志行
        char timestamp[32], level_str[16], process_name[64], message[512];
        if (sscanf(line, "[%31[^]]] [%15[^]]] [%63[^]]] %511[^\n]",
                   timestamp, level_str, process_name, message) == 4) {
            
            // 转换级别字符串为枚举
            clog_level_t level = (clog_level_t)-1;
            if (strcmp(level_str, "I") == 0) level = CLOG_INFO;
            else if (strcmp(level_str, "D") == 0) level = CLOG_DEBUG;
            else if (strcmp(level_str, "W") == 0) level = CLOG_WARNING;
            else if (strcmp(level_str, "E") == 0) level = CLOG_ERROR;
            
            if (level != (clog_level_t)-1) {
                log_message_t msg;
                msg.level = level;
                strcpy(msg.process_name, process_name);
                strcpy(msg.timestamp, timestamp);
                strcpy(msg.message, message);
                
                if (should_display_log(&msg, filter)) {
                    print_log_message(&msg);
                }
            }
        }
    }
    
    pclose(pipe);
    return NULL;
}

int main(int argc, char* argv[]) {
    filter_t filter = {0};
    filter.show_all_processes = 1;
    filter.show_all_levels = 1;
    
    // 解析命令行参数
    int opt;
    while ((opt = getopt(argc, argv, "p:l:h")) != -1) {
        switch (opt) {
            case 'p':
                strcpy(filter.process_filter, optarg);
                filter.show_all_processes = 0;
                break;
            case 'l':
                filter.level_filter = parse_log_level(optarg);
                if (filter.level_filter == (clog_level_t)-1) {
                    fprintf(stderr, "Invalid log level: %s\n", optarg);
                    return 1;
                }
                filter.show_all_levels = 0;
                break;
            case 'h':
                print_usage(argv[0]);
                return 0;
            default:
                print_usage(argv[0]);
                return 1;
        }
    }
    
    // 启动日志读取线程
    pthread_t reader_thread;
    if (pthread_create(&reader_thread, NULL, log_reader, &filter) != 0) {
        perror("pthread_create failed");
        return 1;
    }
    
    // 等待线程结束
    pthread_join(reader_thread, NULL);
    
    return 0;
}
